package org.crumbleworks.crumbcrane.entity;

import org.newdawn.slick.Color;
import org.newdawn.slick.opengl.Texture;

public abstract class Entity2D {
    protected int entityID;
    protected final long randomID;
    
    protected float x, y, width, height;
    private Color color;
    private Texture texture;

    public Entity2D(float x, float y, float width, float height, float r, float g, float b, Texture texture) {
        randomID = Entity2DUtilities.generateRandomID();
        
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;

        color = new Color(r, g, b);
    }
    
    public Entity2D(float x, float y, float width, float height, Color color, Texture texture) {
        randomID = Entity2DUtilities.generateRandomID();
        
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;

        this.color = color;
    }
    
    /**
     * Base implementation.
     */
    public void draw() {
        
    }
    
    /**
     * Checks wheter the passed coordinates are within the coordinates of this entity.
     *
     * @param x the x-coordinate
     * @param y the y-coordinate
     * @return true, if within
     */
    public boolean inBounds(float x, float y, float width, float height) {
        boolean xOK = false;
        boolean yOK = false;

        if((x >= this.x) && ((x + width) <= (this.x + this.width))) {
            xOK = true;
        }
        if((y >= this.y) && ((y + height) <= (this.y + this.height))) {
            yOK = true;
        }

        return (xOK && yOK) ? true : false;
    }

    /**
     * Checks wheter the passed coordinates in the array are within the coordinates of this entity.
     *
     * @param location the array with the two coordinates
     * @return true, if within
     */
    public boolean inBounds(float[] location, float size[]) {
        return inBounds(location[0], location[1], size[0], size[1]);
    }

    /**
     * Checks wheter the coordinates of the passed entity are within the coordinates of this entity.
     *
     * @param otherEntity the other entity
     * @return true, if within
     */
    public boolean inBounds(Entity2D otherEntity) {
        return inBounds(otherEntity.getX(), otherEntity.getY(), otherEntity.getWidth(), otherEntity.getHeight());
    }

    /**
     * Checks wheter an entity with the passed attributes intersects this entity.
     *
     * @param x the x-coordinate
     * @param y the y-coordinate
     * @param width the width
     * @param height the height
     * @return true, if intersects
     */
    public boolean intersects(float x, float y, float width, float height) {
        if (this.x + this.width <= x || this.y + this.height <= y) {
            return false;
        }
        if (x + width <= this.x || y + height <= this.y) {
            return false;
        }

        return true;
    }

    /**
     * Checks wheter an entity with the passed attributes in the arrays intersects this entity.
     *
     * @param location the location
     * @param size the size
     * @return true, if intersects
     */
    public boolean intersects(float[] location, float size[]) {
        return intersects(location[0], location[1], size[0], size[1]);
    }

    /**
     * Checks wheter the passed entity intersects this entity.
     *
     * @param otherEntity the other entity
     * @return true, if intersects
     */
    public boolean intersects(Entity2D otherEntity) {
        return intersects(otherEntity.getX(), otherEntity.getY(), otherEntity.getWidth(), otherEntity.getHeight());
    }

    public int getEntityID() {
        return entityID;
    }

    public void setEntityID(int entityID) {
        this.entityID = entityID;
    }

    public long getRandomID() {
        return randomID;
    }

    public float[] getLocation() {
        float[] location = {x, y };
        return location;
    }

    public void setLocation(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public void setLocation(float[] location) {
        setLocation(location[0], location[1]);
    }

    public float[] getSize() {
        float[] size = {width, height };
        return size;
    }

    public void setSize(float width, float height) {
        this.width = width;
        this.height = height;
    }

    public void setSize(float[] size) {
        setSize(size[0], size[1]);
    }

    public Color getColor() {
        return color;
    }

    public void setColor(float r, float g, float b) {
        color.r = r;
        color.g = g;
        color.b = b;
    }

    public void setColor(float[] color) {
        setColor(color[0], color[1], color[2]);
    }

    public void setColor(Color color) {
        setColor(color.r, color.g, color.b);
    }

    public float getX() {
        return x;
    }

    public void setX(float x) {
        this.x = x;
    }

    public float getY() {
        return y;
    }

    public void setY(float y) {
        this.y = y;
    }

    public float getWidth() {
        return width;
    }

    public void setWidth(float width) {
        this.width = width;
    }

    public float getHeight() {
        return height;
    }

    public void setHeight(float height) {
        this.height = height;
    }

    public float getR() {
        return color.r;
    }

    public void setR(float r) {
        color.r = r;
    }

    public float getG() {
        return color.g;
    }

    public void setG(float g) {
        color.g = g;
    }

    public float getB() {
        return color.b;
    }

    public void setB(float b) {
        color.b = b;
    }

    public Texture getTexture() {
        return texture;
    }

    public void setTexture(Texture texture) {
        this.texture = texture;
    }

    @Override
    public String toString() {
        StringBuffer temp = new StringBuffer();

        temp.append("id=[entity=" + entityID + ", random=" + randomID + "], ");
        temp.append("location=[x=" + x + ", y=" + y + "], ");
        temp.append("size=[width=" + width + ", height=" + height + "], ");
        temp.append("color=[r=" + color.r + ", g=" + color.g + ", b=" + color.b + "]");

        return new String(temp);
    }
}

